package com.ruoyi.quartz.task;

import com.ruoyi.common.constant.CommonConstants;
import com.ruoyi.common.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;

/**
 * description: 数据库操作定时任务
 * date: 2022年03月31日 10:22
 * author: tmac-1
 * version: 1.0
 */
@Component("databaseTask")
@Slf4j
public class DatabaseTask {
    @Value("${spring.datasource.druid.master.url}")
    private String url;
    @Value("${spring.datasource.druid.master.username}")
    private String userName;
    @Value("${spring.datasource.druid.master.password}")
    private String password;
    @Value("${ruoyi.databaseBackupPath}")
    private String databaseBackupPath;

    public static final String MYSQL_STR = "mysql";

    public static final String SQL_SUFFIX = ".sql";


    /**
     * 获取数据库名
     */
    private String getDataBaseName() {
        return url.substring(url.indexOf(CommonConstants.MYSQL_PORT.toString()),
                url.indexOf(CommonConstants.E_QUESTION_MARK)).replaceAll(CommonConstants.SLASH, CommonConstants.EMPTY_STR)
                .replaceAll(CommonConstants.MYSQL_PORT.toString(), CommonConstants.EMPTY_STR);
    }

    /**
     * 获取主机地址
     */
    private String getHost() {
        return url.substring(url.indexOf(MYSQL_STR),
                url.indexOf(CommonConstants.MYSQL_PORT.toString())).replace(CommonConstants.E_COLON, CommonConstants.EMPTY_STR).
                replace(CommonConstants.DOUBLE_SLASH, CommonConstants.EMPTY_STR).
                replace(MYSQL_STR, CommonConstants.EMPTY_STR);
    }

    /**
     * 备份数据库(保留最近5次备份)
     */
    public void backupDatabase() {
        String databaseName = this.getDataBaseName();
        String[] urlParts = url.split(":");
        String port = urlParts[CommonConstants.THREE].split(CommonConstants.SLASH)[CommonConstants.ZERO];
        try {
            log.info("备份数据库[" + databaseName + "]开始");
            // 数据库文件名称
            StringBuilder sb = new StringBuilder();
            sb.append(databaseName);
            sb.append(CommonConstants.UNDER_SCORE);
            sb.append(DateUtils.parseDateToStr(DateUtils.YYYYMMDD, DateUtils.calculateEndDate(DateUtils.getNowDate(), CommonConstants.MINUS_FIVE)));
            sb.append(SQL_SUFFIX);
            File historyFile = new File(databaseBackupPath + sb);
            File backupDirectory = new File(databaseBackupPath);
            if (historyFile.exists() && backupDirectory.listFiles().length >= CommonConstants.FIVE) {
                historyFile.delete();
                log.info("删除备份[" + sb + "]");
            }
            sb.setLength(CommonConstants.ZERO);
            sb.append(databaseName);
            sb.append(CommonConstants.UNDER_SCORE);
            sb.append(DateUtils.parseDateToStr(DateUtils.YYYYMMDD, DateUtils.getNowDate()));
            sb.append(SQL_SUFFIX);
            String mysqlFileName = sb.toString();
            // 备份命令
            sb.setLength(CommonConstants.ZERO);
            sb.append("mysqldump ");
            sb.append("--no-tablespaces ");
            sb.append("-h");
            sb.append(this.getHost());
            sb.append(" -u");
            sb.append(userName);
            sb.append(" -p");
            sb.append(password);
            sb.append(" -P");
            sb.append(port);
            sb.append(" ");
            sb.append(databaseName);
            sb.append(" > ");
            sb.append(databaseBackupPath);
            sb.append(mysqlFileName);
            log.info("备份命令：" + sb);
            File file = new File(databaseBackupPath);
            if (!file.exists()) {
                file.mkdirs();
                log.info("创建目录：" + databaseBackupPath);
            }
            // 获取操作系统名称
            String osName = System.getProperty("os.name").toLowerCase();
            String[] command = new String[CommonConstants.ZERO];
            if (osName.startsWith("windows")) {
                // Windows
                command = new String[]{"cmd", "/c", String.valueOf(sb)};
            } else if (osName.startsWith("linux")) {
                // Linux
                command = new String[]{"/bin/sh", "-c", String.valueOf(sb)};
            }
            // 获取Runtime实例
            Process process = null;
            process = Runtime.getRuntime().exec(command);
            if (process.waitFor() == CommonConstants.ZERO) {
                log.info("备份数据库[" + databaseName + "]结束，备份文件名：" + mysqlFileName);
            } else {
                log.error("备份数据库[" + databaseName + "]失败，网络异常");
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            log.error("备份数据库[" + databaseName + "]异常");
        }
    }

}
